#pragma once

#include <iostream>
#include <string>
#include <functional>
#include <pthread.h>
#include <cassert>

class Thread;

//  上下文，当成一个大号的结构体
class Context
{
public:
    Thread *_this;
    void *_args;

public:
    Context()
        : _this(nullptr), _args(nullptr)
    {
    }
    ~Context()
    {
    }
};

// 线程封装
class Thread
{
public:
    // using func_t = std::function<void* (void*)>;
    typedef std::function<void *(void *)> func_t;
    const int num = 1024;

public:
    Thread(func_t func, void *args, int number)
        : _func(func), _args(args)
    {
        char buffer[num];
        snprintf(buffer, sizeof buffer, "thread-%d", number);
        _name = buffer;
    }

    // 在类内创建线程，想让线程执行对应的方法，需要将方法设置成为static，减少this指针
    static void *start_routine(void *args)
    {
        Context *ctx = static_cast<Context *>(args);
        void *ret = ctx->_this->run(ctx->_args);
        delete ctx;
        return ret;
        // 静态方法不能调用成员方法或者成员变量
    }

    void start()
    {
        Context *ctx = new Context();
        ctx->_this = this;
        ctx->_args = _args;
        int n = pthread_create(&_tid, nullptr, start_routine, ctx);
        assert(n == 0);
        (void)n;
    }

    void join()
    {
        int n = pthread_join(_tid, nullptr);
        assert(n == 0);
        (void)n;
    }

    void *run(void *args)
    {
        _func(args);
    }

    ~Thread()
    {
        // do nothing
    }

private:
    std::string _name;
    pthread_t _tid;
    func_t _func;
    void *_args;
};